cmake_minimum_required(VERSION 3.10.2)

###########################################################
#### Project configuration                             ####
###########################################################

project(MMMSegmenter)

###########################################################
#### Source configuration                              ####
###########################################################

set(SOURCE_FILES
    ${PROJECT_SOURCE_DIR}/MMMSegmenter.cpp
    ${PROJECT_SOURCE_DIR}/MatrixOperation.cpp
    ${PROJECT_SOURCE_DIR}/PCA.cpp
)

set(HEADER_FILES
    ${PROJECT_SOURCE_DIR}/MatrixOperation.h
    ${PROJECT_SOURCE_DIR}/PCA.h
)

###########################################################
#### CMake package configuration                       ####
###########################################################

find_package(MMMCore REQUIRED)
set(EXTERNAL_LIBRARY_DIRS ${EXTERNAL_LIBRARY_DIRS} MMMCore)

find_package(Simox REQUIRED)
set(EXTERNAL_LIBRARY_DIRS ${EXTERNAL_LIBRARY_DIRS} VirtualRobot)

set(EXTERNAL_LIBRARY_DIRS ${EXTERNAL_LIBRARY_DIRS} MMMSimoxTools)

find_package(GSL REQUIRED)
set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${GSL_INCLUDE_DIR})
set(EXTERNAL_LIBRARY_DIRS ${EXTERNAL_LIBRARY_DIRS} ${GSL_LIBRARIES})

# create GslWrap target to be used by this project

set(GslWrap_SOURCE_DIR ${PROJECT_SOURCE_DIR}/extern/gslwrap-0.2)

set(GslWrap_SRCS
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_float.cc
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_double.cc
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_int.cc
    ${GslWrap_SOURCE_DIR}/gslwrap/vector_float.cc
    ${GslWrap_SOURCE_DIR}/gslwrap/vector_double.cc
    ${GslWrap_SOURCE_DIR}/gslwrap/vector_int.cc
)

set(GslWrap_INCS
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_float.h
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_double.h
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_int.h
    ${GslWrap_SOURCE_DIR}/gslwrap/vector_double.h
    ${GslWrap_SOURCE_DIR}/gslwrap/vector_float.h
    ${GslWrap_SOURCE_DIR}/gslwrap/vector_int.h
    ${GslWrap_SOURCE_DIR}/gslwrap/permutation.h
    ${GslWrap_SOURCE_DIR}/gslwrap/histogram.h
    ${GslWrap_SOURCE_DIR}/gslwrap/matrix_vector_operators.h
    ${GslWrap_SOURCE_DIR}/gslwrap/min_fminimizer.h
    ${GslWrap_SOURCE_DIR}/gslwrap/multimin_fdfminimizer.h
    ${GslWrap_SOURCE_DIR}/gslwrap/random_generator.h
    ${GslWrap_SOURCE_DIR}/gslwrap/random_number_distribution.h
)

add_library(GslWrap OBJECT ${GslWrap_SRCS} ${GslWrap_INCS}) # OBJECT does not link - use obj files directly

# this allows dependant targets to automatically add include-dirs by simply linking against this project
target_include_directories(GslWrap PUBLIC
    $<BUILD_INTERFACE:${GslWrap_SOURCE_DIR}>
    $<INSTALL_INTERFACE:include>
)

add_custom_command(
    OUTPUT ${GslWrap_SOURCE_DIR}/gslwrap/generated.timestamp
    WORKING_DIRECTORY ${GslWrap_SOURCE_DIR}/gslwrap
    COMMAND ${GslWrap_SOURCE_DIR}/gslwrap/generate
    COMMAND ${CMAKE_COMMAND} -E touch generated.timestamp # use this to determine last time generated
    DEPENDS ${GslWrap_SOURCE_DIR}/gslwrap/generate
)

add_custom_target(libgslwrap_generator DEPENDS ${GslWrap_SOURCE_DIR}/gslwrap/generated.timestamp)

# ensure sources are being generated
add_dependencies(GslWrap libgslwrap_generator)

# Because OBJECT libraries cannot be linked against, there is
# no way to make use of the target_include_directories
# functionality (because headers are included in
# target_link_libraries). The following is one of the only
# ways to still query the result in a sane way.
set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} "$<TARGET_PROPERTY:GslWrap,INTERFACE_INCLUDE_DIRECTORIES>")

###########################################################
#### Project build configuration                       ####
###########################################################

add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES} $<TARGET_OBJECTS:GslWrap>)
target_link_libraries(${PROJECT_NAME} PUBLIC ${EXTERNAL_LIBRARY_DIRS} dl)

#GET_FILENAME_COMPONENT (CurrentPath ${CMAKE_CURRENT_LIST_FILE} PATH)

install(
    TARGETS ${PROJECT_NAME}
    EXPORT "${CMAKE_PROJECT_NAME}Targets"
    #LIBRARY DESTINATION lib
    #ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
    #INCLUDES DESTINATION include
    COMPONENT bin
)

add_definitions(-DMMMTools_LIB_DIR="${MMMTools_LIB_DIR}")

###########################################################
#### Compiler configuration                            ####
###########################################################

include_directories(${EXTERNAL_INCLUDE_DIRS})
link_directories(${EXTERNAL_LIBRARY_DIRS})
add_definitions(${EXTERNAL_LIBRARY_FLAGS})